﻿using System;
using System.Collections.Generic;
using System.Data;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace EVTEST
{
    public class EVCharge_tc:EVChargeParent
    {
        IPAddress HostIP = IPAddress.Parse("127.0.0.1");
        int HostPort = 10055;
        IPEndPoint point;
        private static Socket socket;
        bool flag = true;
        Socket acceptedSocket;

        //private string receivedString = "";
        private bool receivedFlag = false;
        Thread thread_charge = null;
        Thread thread_other = null;

        private bool receivedflag = false;
        static int sendOutTime = 10;
        static int receiveOutTime = 15;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public EVCharge_tc(string ip, string port)
        {
            HostIP = IPAddress.Parse(ip);
            HostPort = Int32.Parse(port);
            //initServer();
        }

        public EVCharge_tc()
        {
            //initServer();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="ip"></param>
        /// <param name="port"></param>
        public void initSocket(string ip, string port)
        {
            HostIP = IPAddress.Parse(ip);
            HostPort = Int32.Parse(port);
        }

        public override bool startService(out string msg)
        {
            LogWrite.WriteInfo("接口[开启服务]");
            if (init_equipment(out msg))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        public override bool stopService(out string msg)
        {
            LogWrite.WriteInfo("接口[结束服务]");
            msg = "";
            try
            {
                if (socket != null)
                    socket.Close();
                if (thread_charge != null && thread_charge.IsAlive)
                {
                    try
                    {
                        thread_charge.Abort();
                    }
                    catch
                    { }
                }
                if (thread_other != null && thread_other.IsAlive)
                {
                    try
                    {
                        thread_other.Abort();
                    }
                    catch
                    { }
                }
                return true;
            }
            catch (Exception er)
            {
                msg = er.Message;
                return false;
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool init_equipment(out string msg)
        {
            msg = "";
            try
            {
                point = new IPEndPoint(HostIP, HostPort);
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(point);
                if (myLED_OBD_connected != null) myLED_OBD_connected.Invoke(new Action(() => { if (myLED_OBD_connected != null) myLED_OBD_connected.IsLightLed = true; }));
                LogWrite.WriteInfo("初始化连接成功");
                return true;
            }
            catch (Exception ey)
            {
                msg = ey.Message;
                LogWrite.WriteError("初始化连接失败");
                if (myLED_OBD_connected != null) myLED_OBD_connected.Invoke(new Action(() => { if (myLED_OBD_connected != null) myLED_OBD_connected.IsLightLed = false; }));
                return false;
            }
        }
        private bool reconnect()
        {
            try
            {
                if (socket != null) socket.Close();
                point = new IPEndPoint(HostIP, HostPort);
                socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                socket.Connect(point);
                if (myLED_OBD_connected != null) myLED_OBD_connected.Invoke(new Action(() => { if (myLED_OBD_connected != null) myLED_OBD_connected.IsLightLed = true; }));
                LogWrite.WriteInfo("重新连接成功");
                return true;
            }
            catch (Exception ey)
            {
                LogWrite.WriteError("重新连接失败");
                if (myLED_OBD_connected != null) myLED_OBD_connected.Invoke(new Action(() => { if (myLED_OBD_connected != null) myLED_OBD_connected.IsLightLed = false; }));
                return false;
            }
        }
        /// <summary>
        /// 向远程主机发送数据
        /// </summary>
        /// <param name="socket">连接到远程主机的socket</param>
        /// <param name="buffer">待发送数据</param>
        /// <param name="outTime">发送超时时长，单位是秒(为-1时，将一直等待直到有数据需要发送)</param>
        /// <returns>0:发送成功；-1:超时；-2:出现错误；-3:出现异常</returns>
        public bool SendData(byte[] buffer, out string msg)
        {
            msg = "";
            if (socket == null || socket.Connected == false)
            {
                LogWrite.WriteError("参数socket为null，或者未连接到远程计算机");
                //if(myLED_OBD_connected!=null)myLED_OBD_connected.Invoke(new Action(() => { if(myLED_OBD_connected!=null)myLED_OBD_connected.IsLightLed = false; }));

                if (!reconnect())
                {
                    msg = "OBD未连接";
                    return false;
                }
            }
            if (buffer == null || buffer.Length == 0)
            {
                LogWrite.WriteError("发送数据失败，参数buffer为null ,或者长度为 0");
                msg = "发送数据失败，参数buffer为null ,或者长度为 0";
                return false;
            }

            int flag = 0;
            try
            {
                int left = buffer.Length;
                int sndLen = 0;
                int hasSend = 0;

                while (true)
                {
                    if ((socket.Poll(sendOutTime * 1000, SelectMode.SelectWrite) == true))
                    {
                        // 收集了足够多的传出数据后开始发送
                        sndLen = socket.Send(buffer, hasSend, left, SocketFlags.None);
                        left -= sndLen;
                        hasSend += sndLen;

                        // 数据已经全部发送
                        if (left == 0)
                        {
                            flag = 0;
                            msg = "发送成功";
                            return true;
                        }
                        else
                        {
                            // 数据部分已经被发送
                            if (sndLen > 0)
                            {
                                continue;
                            }
                            else // 发送数据发生错误
                            {
                                flag = -2;
                                msg = "发送数据发生错误";
                                return false;
                            }
                        }
                    }
                    else // 超时退出
                    {
                        flag = -1;
                        msg = "发送数据超时";
                        return false;
                    }
                }
            }
            catch (Exception er)
            {
                //Log
                LogWrite.WriteError("发送数据过程发生异常：" + er.Message);
                msg = "发送数据过程发生异常：" + er.Message;
                return false;
            }
            //return "发送完毕";
        }
        /// <summary>
        /// 向远程主机发送数据
        /// </summary>
        /// <param name="socket">连接到远程主机的socket</param>
        /// <param name="buffer">待发送的字符串</param>
        /// <param name="outTime">发送数据的超时时间，单位是秒(为-1时，将一直等待直到有数据需要发送)</param>
        /// <returns>0:发送数据成功；-1:超时；-2:错误；-3:异常</returns>
        public bool SendData(Socket socket, string buffer, out string msg)
        {
            return SendData(System.Text.Encoding.Default.GetBytes(buffer), out msg);
        }
        /// <summary>
        /// 接收远程主机发送的数据
        /// </summary>
        /// <param name="socket">要接收数据且已经连接到远程主机的</param>
        /// <param name="buffer">接收数据的缓冲区(需要接收的数据的长度，由 buffer 的长度决定)</param>
        /// <param name="outTime">接收数据的超时时间，单位秒(指定为-1时，将一直等待直到有数据需要接收)</param>
        /// <returns></returns>
        public int RecvData(Socket socket, out List<string> MessageList)
        {
            byte[] buffer = new byte[10240];
            MessageList = new List<string>();
            string receivedMessage = "";
            if (socket == null || socket.Connected == false)
            {
                LogWrite.WriteError("socket为null，或者未连接到远程计算机");
                return 0;
            }
            buffer.Initialize();
            int left = buffer.Length;
            int curRcv = 0;
            int hasRecv = 0;
            int flag = 0;
            int receiveOutCount = 0;
            try
            {
                while (true)
                {
                    if (socket.Poll(receiveOutTime * 1000, SelectMode.SelectRead) == true)
                    {
                        // 已经有数据等待接收
                        curRcv = socket.Receive(buffer, hasRecv, left, SocketFlags.None);
                        left -= curRcv;
                        hasRecv += curRcv;
                        string s = System.Text.Encoding.UTF8.GetString(buffer, 0, hasRecv);
                        LogWrite.WriteInfo("接收到数据：" + s);
                        //string s = Encoding.gbk.GetString(buffer, 0, hasRecv);//将已接收到的转换化字符串，以"/Message"为结束判断
                        // 数据已经全部接收 
                        bool isReceiveFinished = (s.Trim()).EndsWith("#");
                        if (isReceiveFinished)
                        {
                            LogWrite.WriteInfo("内容正确");
                            string leftstring = s;
                            //receivedMessage = s.Substring(11, s.Length - 12);
                            int msgcount = 1;
                            while(leftstring.IndexOf("#")>0)
                            {

                                LogWrite.WriteInfo("第"+(msgcount++).ToString()+"条数据");
                                int index2 = leftstring.IndexOf("#");
                                if (index2 > 11)
                                {
                                    receivedMessage = leftstring.Substring(11, index2 - 12);
                                    MessageList.Add(receivedMessage);
                                    if (leftstring.Length > index2 + 1)
                                    {
                                        leftstring = leftstring.Substring(index2 + 1, leftstring.Length - index2 - 1);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                else
                                {
                                    break;
                                }
                            }
                            flag = 1;
                            break;
                        }
                        else
                        {
                            LogWrite.WriteInfo("内容错误");
                            flag = 0;
                            break;
                        }
                        /*
                        else
                        {
                            JbtNetLibrary.LogWrite.WriteInfo("数据未接收完毕");
                            // 数据已经部分接收
                            if (curRcv > 0)
                            {
                                continue;
                            }
                            else  // 出现错误
                            {
                                flag = -2;
                                break;
                            }
                        }*/
                    }
                    else // 超时退出
                    {
                        Thread.Sleep(1000);
                        receiveOutCount++;
                        if (receiveOutCount >= receiveOutTime)
                        {
                            LogWrite.WriteInfo("接收数据超时");
                            flag = -1;
                            break;
                        }
                    }
                }
            }
            catch (SocketException)
            {
                //Log
                flag = -3;
            }
            return flag;
        }

        /// <summary>  
        /// 将XmlDocument转化为string  
        /// </summary>  
        /// <param name="xmlDoc"></param>  
        /// <returns></returns>  
        static byte[] ConvertXmlToString(XmlDocument xmlDoc)
        {
            MemoryStream stream = new MemoryStream();
            XmlTextWriter writer = new XmlTextWriter(stream, null);
            writer.Formatting = Formatting.Indented;
            xmlDoc.Save(writer);
            StreamReader sr = new StreamReader(stream, System.Text.Encoding.UTF8);
            stream.Position = 0;
            string xmlString = sr.ReadToEnd();
            // int versionindex=xmlString.IndexOf('>');
            //xmlString = xmlString.Remove(0, versionindex + 1);
            sr.Close();
            stream.Close();
            //xmlString = xmlString.Replace(" ", "");
            string newstring = xmlString.Replace("\r\n", "");
            newstring = newstring.Replace("xml version=\"1.0\"", "xml version=\"1.0\" encoding=\"UTF-8\"");//.Replace(" ", "%20").Replace("\r\n", "%0d%0a") + "\r\n";

            //saveLogInf(newstring);
            byte[] bufferToSend = System.Text.Encoding.UTF8.GetBytes(newstring);
            int length = bufferToSend.Length + 12;
            newstring = "ZDEPS" + length.ToString("000000") + newstring + "#";
            LogWrite.WriteInfo("SEND:\r\n" + newstring);
            byte[] bufferToSend2 = System.Text.Encoding.UTF8.GetBytes(newstring);
            //byte[] bufferToSend = System.Text.Encoding.UTF8.GetBytes(newstring);
            return bufferToSend2;
        }
        Data_charge chargedatareal;
        private bool isChargeTesting = false;
        private bool isChargeFinished = false;
        private bool isStartCharge = false;
        private string ChargeACK_code = "";
        private string ChargeACK_msg = "";
        public override bool startChargeTest(out string code, out string msg)
        {
            //socket.Connect(point);
            code = "0";
            msg = "";
            if(thread_charge != null&& thread_charge.IsAlive)
            {
                code = "-1";
                msg = "读取数据进程还在进行中";
                return false;
            }
            XmlDocument xmldoc, xlmrecivedoc;
            XmlNode xmlnode;
            XmlElement xmlelem;
            DataTable dt = null;
            xmldoc = new XmlDocument();
            xmlelem = xmldoc.CreateElement("", "request", "");
            xmldoc.AppendChild(xmlelem);
            XmlNode root = xmldoc.SelectSingleNode("request");//查找<Employees> 
            XmlElement cmd = xmldoc.CreateElement("cmd");//创建一个<Node>节点  
            cmd.InnerText = "GetChargeDetection";
            root.AppendChild(cmd);
            if (!SendData(ConvertXmlToString(xmldoc), out msg))
            {
                return false;
            }
            isChargeFinished = false;
            isChargeTesting = true;
            isStartCharge = false;
            thread_charge = new Thread(waitChargeTestData);
            thread_charge.Start();
            return true;
        }

        /// <summary>
        /// 过程数据读取线程
        /// </summary>
        private void waitChargeTestData()
        {
            while(isChargeTesting)
            {
                List<string> msglist = new List<string>();
                if (RecvData(socket, out msglist) > 0 && msglist.Count > 0)
                {
                    foreach (string receivedString in msglist)
                    {
                        try
                        {
                            DataSet ds = new DataSet();
                            StringReader stream = new StringReader(receivedString);
                            XmlTextReader reader = new XmlTextReader(stream);
                            ds.ReadXml(reader);
                            DataTable dt1 = ds.Tables["response"];
                            string cmdname = dt1.Rows[0]["cmd"].ToString();
                            ChargeACK_code = dt1.Rows[0]["code"].ToString();
                            ChargeACK_msg = dt1.Rows[0]["msg"].ToString();
                            if (cmdname == "GetChargeDetection")//3min测试结束
                            {
                                if (ChargeACK_code == "2")
                                {
                                    DataTable dt2 = ds.Tables["data"];
                                    chargedatareal.BatteryMaxTemp = dt2.Rows[0]["BatteryMaxTemp"].ToString();// 动力蓄电池最高温度 字符串 否 ℃
                                    chargedatareal.BatteryCellMaxVolt = dt2.Rows[0]["BatteryCellMaxVolt"].ToString();//单体电池最高电压 字符串 否 V
                                    chargedatareal.BatteryCellVoltRange = dt2.Rows[0]["BatteryCellVoltRange"].ToString();//单体蓄电池电压极差 字符串 否 V
                                    chargedatareal.BatteryMaxTempNum = dt2.Rows[0]["BatteryMaxTempNum"].ToString();// 单体蓄电池最高温度所在编号 字符串 否
                                    chargedatareal.BatteryCellMaxVoltNum = dt2.Rows[0]["BatteryCellMaxVoltNum"].ToString();// 单体蓄电池最高电压所在编号 字符串 否
                                    chargedatareal.BatteryMinTemp = dt2.Rows[0]["BatteryMinTemp"].ToString();// 单体蓄电池最低温度 字符串 否 ℃
                                    chargedatareal.BatteryMinTempNum = dt2.Rows[0]["BatteryMinTempNum"].ToString();//单体蓄电池最低温度所在编号 字符串 否 ℃
                                    chargedatareal.ChargingVoltageMeter = dt2.Rows[0]["ChargingVoltageMeter"].ToString();// 充电电压测量值 字符串 否 V
                                    chargedatareal.ChargingCurrentMeter = dt2.Rows[0]["ChargingCurrentMeter"].ToString();// 充电电流测量值 字符串 否 A
                                    chargedatareal.SOC = dt2.Rows[0]["SOC"].ToString();//当前荷点状态 SOC 字符串 否 %
                                    chargedatareal.OutputVoltage = dt2.Rows[0]["OutputVoltage"].ToString();// 电压输出值 字符串 否 V
                                    chargedatareal.OutputCurrent = dt2.Rows[0]["OutputCurrent"].ToString();// 电流输出值 字符串 否 A
                                    chargedatareal.DemandVoltage = dt2.Rows[0]["DemandVoltage"].ToString();//电压需求 字符串 否 V
                                    chargedatareal.DemandCurrent = dt2.Rows[0]["DemandCurrent"].ToString();// 电流需求 字符串 否 A
                                    chargedatareal.ChargingMode = dt2.Rows[0]["ChargingMode"].ToString();// 充电模式(1:恒压；2：恒流) 字符串 否
                                    chargedatareal.MaxAllowChargingVoltage = dt2.Rows[0]["MaxAllowChargingVoltage"].ToString();// 单体动力电池最高允许充电电压 字符串 否 V
                                    chargedatareal.MaxAllowChargingCurrent = dt2.Rows[0]["MaxAllowChargingCurrent"].ToString();// 最高允许充电电流 字符串 否 A
                                    chargedatareal.TotalEnergy = dt2.Rows[0]["TotalEnergy"].ToString();// 动力电池标称总能量 字符串 否 Kw·h
                                    chargedatareal.MaxAllowTotalVoltage = dt2.Rows[0]["MaxAllowTotalVoltage"].ToString();// 最高允许充电总电压 字符串 否 V
                                    chargedatareal.MaxAllowChargingTemp = dt2.Rows[0]["MaxAllowChargingTemp"].ToString();// 最高允许充电温度 字符串 否 ℃
                                    chargedatareal.VehicleSOC = dt2.Rows[0]["VehicleSOC"].ToString();// 整车动力蓄电池荷点状态 字符串 否 %
                                    chargedatareal.BatteryVoltage = dt2.Rows[0]["BatteryVoltage"].ToString();//整车动力蓄电池当前电池电压 字符串 否 V
                                    chargedatareal.BatteryType = dt2.Rows[0]["BatteryType"].ToString();// 电池类型 字符串 否
                                    chargedatareal.BatteryPackNum = dt2.Rows[0]["BatteryPackNum"].ToString();// BMS 电池组序号 字符串 否
                                    chargedatareal.BatteryCellMinVolt = dt2.Rows[0]["BatteryCellMinVolt"].ToString();// 单体电池最低电压 字符串 是

                                    if (!isStartCharge && dt2.Rows[0]["ChargeState"].ToString() == "1")//ChargeState：充电时状态(0$连接&1$充电&2$结束)
                                    {
                                        isStartCharge = true;//从开始收到数据开始认为充电正式开始
                                    }
                                }
                                else if (ChargeACK_code == "0")
                                {
                                    isChargeFinished = true;
                                    isChargeTesting = false;
                                }
                                else if (ChargeACK_code == "1")
                                {
                                    isChargeTesting = false;
                                    isChargeFinished = false;
                                }
                                else if (ChargeACK_code == "3")
                                {
                                    isChargeTesting = false;
                                    isChargeFinished = false;
                                }
                                else
                                {
                                    isChargeTesting = false;
                                    isChargeFinished = false;
                                }
                            }
                        }
                        catch (Exception er)
                        {
                            LogWrite.WriteInfo("解析出现异常:" + er.Message + "\r\n");
                        }
                    }
                }
                else
                {
                    ChargeACK_code = "-1";
                    ChargeACK_msg = "超时未响应";
                    isChargeTesting = false;
                    isChargeFinished = false;
                }

                Thread.Sleep(500);
            }
        }

        public override bool getChargeTestData(out Data_charge data,out bool isStartCharge, out string code, out string msg)
        {
            isStartCharge = this.isStartCharge;
            code = ChargeACK_code;
            msg = ChargeACK_msg;
            data = chargedatareal;
            return true;
        }

        public override bool getChargeResultData(out Data_charge data, out string code, out string msg)
        {
            code = "0";
            msg = "";
            data = new Data_charge();
            
            XmlDocument xmldoc;
            XmlElement xmlelem;
            xmldoc = new XmlDocument();
            xmlelem = xmldoc.CreateElement("", "request", "");
            xmldoc.AppendChild(xmlelem);
            XmlNode root = xmldoc.SelectSingleNode("request");//查找<Employees> 
            XmlElement cmd = xmldoc.CreateElement("cmd");//创建一个<Node>节点  
            cmd.InnerText = "GetChargeResult";
            root.AppendChild(cmd);

            bool send_flag = false;
            for (int i = 0; i < 3; i++)
            {
                if (SendData(ConvertXmlToString(xmldoc), out msg))
                {
                    send_flag = true;
                    break;
                }
            }

            if (send_flag)
            {
                //发送成功，等待结果返回
                DateTime start_time = DateTime.Now;
                List<byte> All_Content_byte = new List<byte>();

                while (true)
                {
                    try
                    {
                        #region 数据接收
                        if (socket.Connected && socket.Available > 0)
                        {
                            int read_buffer_length = socket.Available;
                            byte[] ReadBuffer = new byte[read_buffer_length];
                            socket.Receive(ReadBuffer, read_buffer_length, SocketFlags.None);
                            All_Content_byte.AddRange(ReadBuffer.ToList());
                        }
                        #endregion

                        #region 数据处理
                        if (All_Content_byte.Count > 120)
                        {
                            string receiveStr = Encoding.UTF8.GetString(All_Content_byte.ToArray());

                            int index = receiveStr.IndexOf("ZDEPS");
                            if (index < 0)
                            {
                                All_Content_byte.Clear();
                                continue;
                            }
                            else if (index > 0)
                            {
                                All_Content_byte.RemoveRange(0, index);
                                receiveStr = receiveStr.Remove(0, index);
                            }

                            //找到帧头且将帧头移到最开始位置，解析
                            if (receiveStr.Length > 120)
                            {
                                index = receiveStr.IndexOf("#");//找帧尾
                                if (index > 120)
                                {
                                    //找到帧尾后，原始缓存数据删除一帧，解析当前一帧数据内容
                                    All_Content_byte.RemoveRange(0, index + 1);
                                    
                                    DataSet ds = new DataSet();
                                    StringReader stream = new StringReader(receiveStr.Substring(0, index).Remove(0, 11));
                                    XmlTextReader reader = new XmlTextReader(stream);
                                    ds.ReadXml(reader);
                                    DataTable dt1 = ds.Tables["response"];

                                    if (dt1.Rows[0]["cmd"].ToString() == "GetChargeResult")
                                    {
                                        code = dt1.Rows[0]["code"].ToString();
                                        msg = dt1.Rows[0]["msg"].ToString();

                                        DataTable dt2 = ds.Tables["data"];
                                        data.BatteryMaxTemp = dt2.Rows[0]["BatteryMaxTemp"].ToString();// 动力蓄电池最高温度 字符串 否 ℃
                                        data.BatteryCellMaxVolt = dt2.Rows[0]["BatteryCellMaxVolt"].ToString();//单体电池最高电压 字符串 否 V
                                        data.BatteryCellVoltRange = dt2.Rows[0]["BatteryCellVoltRange"].ToString();//单体蓄电池电压极差 字符串 否 V
                                        data.BatteryMaxTempNum = dt2.Rows[0]["BatteryMaxTempNum"].ToString();// 单体蓄电池最高温度所在编号 字符串 否
                                        data.BatteryCellMaxVoltNum = dt2.Rows[0]["BatteryCellMaxVoltNum"].ToString();// 单体蓄电池最高电压所在编号 字符串 否
                                        data.BatteryMinTemp = dt2.Rows[0]["BatteryMinTemp"].ToString();// 单体蓄电池最低温度 字符串 否 ℃
                                        data.BatteryMinTempNum = dt2.Rows[0]["BatteryMinTempNum"].ToString();//单体蓄电池最低温度所在编号 字符串 否 ℃
                                        data.ChargingVoltageMeter = dt2.Rows[0]["ChargingVoltageMeter"].ToString();// 充电电压测量值 字符串 否 V
                                        data.ChargingCurrentMeter = dt2.Rows[0]["ChargingCurrentMeter"].ToString();// 充电电流测量值 字符串 否 A
                                        data.SOC = dt2.Rows[0]["SOC"].ToString();//当前荷点状态 SOC 字符串 否 %
                                        data.OutputVoltage = dt2.Rows[0]["OutputVoltage"].ToString();// 电压输出值 字符串 否 V
                                        data.OutputCurrent = dt2.Rows[0]["OutputCurrent"].ToString();// 电流输出值 字符串 否 A
                                        data.DemandVoltage = dt2.Rows[0]["DemandVoltage"].ToString();//电压需求 字符串 否 V
                                        data.DemandCurrent = dt2.Rows[0]["DemandCurrent"].ToString();// 电流需求 字符串 否 A
                                        data.ChargingMode = dt2.Rows[0]["ChargingMode"].ToString();// 充电模式(1:恒压；2：恒流) 字符串 否
                                        data.MaxAllowChargingVoltage = dt2.Rows[0]["MaxAllowChargingVoltage"].ToString();// 单体动力电池最高允许充电电压 字符串 否 V
                                        data.MaxAllowChargingCurrent = dt2.Rows[0]["MaxAllowChargingCurrent"].ToString();// 最高允许充电电流 字符串 否 A
                                        data.TotalEnergy = dt2.Rows[0]["TotalEnergy"].ToString();// 动力电池标称总能量 字符串 否 Kw·h
                                        data.MaxAllowTotalVoltage = dt2.Rows[0]["MaxAllowTotalVoltage"].ToString();// 最高允许充电总电压 字符串 否 V
                                        data.MaxAllowChargingTemp = dt2.Rows[0]["MaxAllowChargingTemp"].ToString();// 最高允许充电温度 字符串 否 ℃
                                        data.VehicleSOC = dt2.Rows[0]["VehicleSOC"].ToString();// 整车动力蓄电池荷点状态 字符串 否 %
                                        data.BatteryVoltage = dt2.Rows[0]["BatteryVoltage"].ToString();//整车动力蓄电池当前电池电压 字符串 否 V
                                        data.BatteryType = dt2.Rows[0]["BatteryType"].ToString();// 电池类型 字符串 否
                                        data.BatteryPackNum = dt2.Rows[0]["BatteryPackNum"].ToString();// BMS 电池组序号 字符串 否

                                        return true;
                                    }
                                }
                            }
                        }
                        #endregion

                        Thread.Sleep(100);
                    }
                    catch { }

                    if ((DateTime.Now - start_time).TotalSeconds > 3)
                    {
                        code = "1";
                        msg = "超时未响应";

                        return false;
                    }
                }
            }
            else
            {
                code = "1";
                msg = "获取结果命令发送失败";
                return false;
            }
        }

        private bool isWaitingACK = false;
        private string ACK_code = "";
        private string ACK_msg = "";
        private DataTable ACK_data = null;
        private void waitOhterTestData(object requestcmd)
        {
            while (isWaitingACK)
            {
                List<string> msglist = new List<string>();
                if (RecvData(socket, out msglist) > 0 && msglist.Count > 0)
                {
                    foreach (string receivedString in msglist)
                    {
                        DataSet ds = new DataSet();
                        StringReader stream = new StringReader(receivedString);
                        XmlTextReader reader = new XmlTextReader(stream);
                        ds.ReadXml(reader);
                        DataTable dt1 = ds.Tables["response"];
                        string cmdname = dt1.Rows[0]["cmd"].ToString();
                        if (cmdname == (string)requestcmd)//3min测试结束
                        {
                            ACK_code = dt1.Rows[0]["code"].ToString();
                            ACK_msg = dt1.Rows[0]["msg"].ToString();
                            if (ds.Tables.Contains("data"))
                                ACK_data = ds.Tables["data"];
                            else
                                ACK_data = null;
                            if (ACK_code == "0" || ACK_code == "1" || ACK_code == "3")
                            {
                                isWaitingACK = false;
                            }
                        }
                    }
                }
                else
                {
                    ACK_code = "-1";
                    ACK_msg = "超时未响应";
                    isWaitingACK = false;
                }
                Thread.Sleep(200);
            }
        }
        private bool testOtherProject(string itemname,out string code,out string msg)
        {
            code = "0";
            msg = "";
            if (thread_other != null && thread_other.IsAlive)
            {
                code = "-1";
                msg = "读取数据进程还在进行中";
                return false;
            }
            XmlDocument xmldoc, xlmrecivedoc;
            XmlNode xmlnode;
            XmlElement xmlelem;
            DataTable dt = null;
            xmldoc = new XmlDocument();
            xmlelem = xmldoc.CreateElement("", "request", "");
            xmldoc.AppendChild(xmlelem);
            XmlNode root = xmldoc.SelectSingleNode("request");//查找<Employees> 
            XmlElement cmd = xmldoc.CreateElement("cmd");//创建一个<Node>节点  
            cmd.InnerText = itemname;
            root.AppendChild(cmd);
            if (!SendData(ConvertXmlToString(xmldoc), out msg))
            {
                return false;
            }
            isWaitingACK = true;
            thread_other = new Thread(new ParameterizedThreadStart(waitOhterTestData));
            thread_other.Start(itemname);
            return true;
        }
        public override bool testDWDS_DCPEAndACPE(out string code, out string msg)
        {
            return testOtherProject("GetDCCathodeAndACCathode",out code,out msg);            
        }
        public override bool getDWDS_DCPEAndACPEData(out Data_DWDS_DCPEAndACPE data, out string code, out string msg)
        {
            data = new Data_DWDS_DCPEAndACPE();
            if(isWaitingACK)
            {
                code = "-2";
                msg = "等待响应";
            }
            else
            {
                code = ACK_code;
                msg = ACK_msg;
                if(code=="0")
                {
                    try
                    {
                        data.value = ACK_data.Rows[0]["DCCathodeAndACCathode"].ToString();
                        return true;
                    }
                    catch(Exception er)
                    {
                        code = "-1";
                        msg ="解析数据出现异常"+ er.Message;
                    }
                }
            }
            return true;
        }
        public override bool testDWDS_PEAndShellPE(out string code, out string msg)
        {
            return testOtherProject("GetCathodeAndShellGrounds", out code, out msg);
            
        }
        public override bool getDWDS_PEAndShellPEData(out Data_DWDS_PEAndShellPE data, out string code, out string msg)
        {
            data = new Data_DWDS_PEAndShellPE();
            if (isWaitingACK)
            {
                code = "-2";
                msg = "等待响应";
            }
            else
            {
                code = ACK_code;
                msg = ACK_msg;
                if (code == "0")
                {
                    try
                    {
                        data.value = ACK_data.Rows[0]["CathodeAndShellGrounds"].ToString();
                        return true;
                    }
                    catch (Exception er)
                    {
                        code = "-1";
                        msg = "解析数据出现异常" + er.Message;
                    }
                }
            }
            return true;
        }
        public override bool testJYDZ_DC(out string code, out string msg)
        {
            return testOtherProject("GetDCInsulationTest", out code, out msg);
        }
        public override bool getJYDZ_DCData(out Data_JYDZ_DC data, out string code, out string msg)
        {
            data = new Data_JYDZ_DC();
            if (isWaitingACK)
            {
                code = "-2";
                msg = "等待响应";
            }
            else
            {
                code = ACK_code;
                msg = ACK_msg;
                if (code == "0")
                {
                    try
                    {
                        data.IRDCChargeSocket = ACK_data.Rows[0]["IRDCChargeSocket"].ToString();
                        data.IRDCPositiveAndPE = ACK_data.Rows[0]["IRDCPositiveAndPE"].ToString();
                        data.IRDCNegativeAndPE = ACK_data.Rows[0]["IRDCNegativeAndPE"].ToString();
                        return true;
                    }
                    catch (Exception er)
                    {
                        code = "-1";
                        msg = "解析数据出现异常" + er.Message;
                    }
                }
            }
            return true;
        }
        public override bool testJYDZ_AC(out string code, out string msg)
        {
            return testOtherProject("GetACInsulationTest", out code, out msg);
        }
        public override bool getJYDZ_ACData(out Data_JYDZ_AC data, out string code, out string msg)
        {
            data = new Data_JYDZ_AC();
            if (isWaitingACK)
            {
                code = "-2";
                msg = "等待响应";
            }
            else
            {
                code = ACK_code;
                msg = ACK_msg;
                if (code == "0")
                {
                    try
                    {
                        data.IRACChargeSocket = ACK_data.Rows[0]["IRACChargeSocket"].ToString();
                        data.IRL1 = ACK_data.Rows[0]["IRL1"].ToString();
                        data.IRL2 = ACK_data.Rows[0]["IRL2"].ToString();
                        data.IRL3 = ACK_data.Rows[0]["IRL3"].ToString();
                        return true;
                    }
                    catch (Exception er)
                    {
                        code = "-1";
                        msg = "解析数据出现异常" + er.Message;
                    }
                }
            }
            return true;
        }
        public override bool abortTest(out string code, out string msg)
        { //socket.Connect(point);
            code = "0";
            msg = "";

            if (thread_charge != null && thread_charge.IsAlive)
            {
                try
                {
                    thread_charge.Abort();
                }
                catch
                { }
            }
            if (thread_other != null && thread_other.IsAlive)
            {
                try
                {
                    thread_other.Abort();
                }
                catch
                { }
            }
            isChargeTesting = false;
            isWaitingACK = false;
            XmlDocument xmldoc, xlmrecivedoc;
            XmlNode xmlnode;
            XmlElement xmlelem;
            DataTable dt = null;
            xmldoc = new XmlDocument();
            xmlelem = xmldoc.CreateElement("", "request", "");
            xmldoc.AppendChild(xmlelem);
            XmlNode root = xmldoc.SelectSingleNode("request");//查找<Employees> 
            XmlElement cmd = xmldoc.CreateElement("cmd");//创建一个<Node>节点  
            cmd.InnerText = "StopTest";
            root.AppendChild(cmd);
            if (!SendData(ConvertXmlToString(xmldoc), out msg))
            {
                return false;
            }
            Thread.Sleep(100);
            byte[] buffer = new byte[10 * 1024];
            List<string> msglist = new List<string>();
            if (RecvData(socket, out msglist) > 0&&msglist.Count>0)
            {
                string receivedString = msglist[0];
                DataSet ds = new DataSet();
                StringReader stream = new StringReader(receivedString);
                XmlTextReader reader = new XmlTextReader(stream);
                ds.ReadXml(reader);
                DataTable dt1 = ds.Tables["response"];
                string cmdname = dt1.Rows[0]["cmd"].ToString();
                code = dt1.Rows[0]["code"].ToString();
                msg = dt1.Rows[0]["msg"].ToString();
                if (code == "0")
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            else
            {
                msg = "接收数据失败";
                return false;
            }
        }
    }
}
